package swag49.dao; import org.slf4j.Logger; import swag49.util.Log; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import javax.persistence.metamodel.Attribute; import javax.persistence.metamodel.EntityType; import javax.persistence.metamodel.Metamodel; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collections; import java.util.List; import java.util.Set; public abstract class AbstractDataAccessObject<T, PK> implements DataAccessObject<T, PK> { @Log private Logger log; private final Class<T> modelClass; public AbstractDataAccessObject(final Class<T> modelClass) { this.modelClass = modelClass; } protected abstract EntityManager getEntityManager(); @Override public boolean contains(T message) { return getEntityManager().contains(message); } @Override public T create(T message) { return getEntityManager().merge(message); } public void detach(T model) { getEntityManager().detach(model); } @Override public void delete(T message) { message = getEntityManager().merge(message); getEntityManager().remove(message); } @Override public T get(PK id) { return getEntityManager().find(modelClass, id); } @SuppressWarnings({"unchecked"}) @Override public List<T> queryByExample(T model) { // EntityManager em = getEntityManager(); // HibernateEntityManager hem = em.unwrap(HibernateEntityManager.class); // Session session = hem.getSession(); // // Criteria criteria = session.createCriteria(modelClass); // // if (model != null) // criteria.add(Example.create(model)); // // return (List<T>) criteria.list(); try { return findByExample(model, modelClass); } catch (Exception e) { log.warn("error finding by example", e); return Collections.emptyList(); } } @Override public T update(T message) { return getEntityManager().merge(message); } private <T> List<T> findByExample(T example, Class<T> clazz) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException { EntityManager em = getEntityManager(); CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<T> cq = cb.createQuery(clazz); Root<T> r = cq.from(clazz); Predicate p = cb.conjunction(); Metamodel mm = em.getMetamodel(); EntityType<T> et = mm.entity(clazz); Set<Attribute<? super T, ?>> attrs = et.getAttributes(); for (Attribute<? super T, ?> a : attrs) { String name = a.getName(); String javaName = a.getJavaMember().getName(); String getter = "get" + javaName.substring(0, 1).toUpperCase() + javaName.substring(1); Method m = clazz.getMethod(getter, (Class<?>[]) null); Object value = m.invoke(example, (Object[]) null); if (value != null) { if (!a.isCollection()) p = cb.and(p, cb.equal(r.get(name), value)); if (a.isAssociation()) r.fetch(name); } } cq.select(r).where(p); TypedQuery<T> query = em.createQuery(cq); return query.getResultList(); } }